package icon.tester;

import swing.Dialog;
import swing.FormPanel;
import swing.Images;

import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;

import static javax.swing.JFileChooser.APPROVE_OPTION;
import static misc.Files.getExtension;
import static swing.Dialog.Flag.CENTERED;
import static swing.Dialog.Flag.PACKED;

public class IconTesterDialog extends Dialog {

    /**
     *
     */
    private static final long serialVersionUID = 1512556822019913321L;
    private static final int WIDTH = 4;
    private static final int HEIGHT = 4;

    private static final int RECURSIVE = -1;
    private static final int PLAIN = 1;

    private final JTabbedPane tabbedPane = new JTabbedPane();
    private final TrayIcon trayIcon;

    public IconTesterDialog(TrayIcon trayIcon) {
        super(CENTERED, PACKED);

        this.trayIcon = trayIcon;
        setLayout(new BorderLayout());
        ConfigPanel configPanel = new ConfigPanel();
        getContentPane().add(configPanel, BorderLayout.NORTH);
        getContentPane().add(tabbedPane);

    }

    private void handle(String tabName, File file, int depth) {
        if (file.isDirectory() && depth != 0)
            handleDirectory(file, depth);
        else
            handleFile(tabName, file);
    }

    private void handleFile(String tabName, File file) {
        if (Arrays.asList(Images.EXTENSIONS).contains(getExtension(file)))
            handleImage(tabName, file);
    }

    private final Map<String, JPanel> tabs = new LinkedHashMap<>();

    private void handleImage(String tabName, File file) {
        if (!tabs.containsKey(tabName)) {
            JPanel tab = new JPanel(new GridLayout(WIDTH, HEIGHT));
            tabbedPane.add(tabName, tab);
            tabs.put(tabName, tab);
        }

        tabs.get(tabName).add(new IconButton(file));
    }

    private void handleDirectory(File directory, int depth) {
        if (directory == null)
            return;

        File[] files = directory.listFiles();

        if (files == null)
            return;

        for (File file : files)
            handle(directory.getName(), file, depth - 1);
    }

    private class IconButton extends JButton {
        /**
         *
         */
        private static final long serialVersionUID = -3403853801435857836L;

        public IconButton(File file) {
            final Image image = Images.LoadImage(file.getAbsolutePath());
            setIcon(new ImageIcon(image));
            addActionListener(e -> trayIcon.setImage(image));
        }
    }

    private class FileChooser extends JFileChooser {
        /**
         *
         */
        private static final long serialVersionUID = 5482257645050509591L;

        public FileChooser() {
            setFileSelectionMode(FILES_AND_DIRECTORIES);
            addChoosableFileFilter(new Images.Filter());
            setAcceptAllFileFilterUsed(false);
            setAccessory(new Images.Preview(this));
            setMultiSelectionEnabled(true);
        }
    }

    private class ConfigPanel extends FormPanel {

        /**
         *
         */
        private static final long serialVersionUID = -2089919147654113010L;
        private final JSpinner depthSpinner = new JSpinner(new SpinnerNumberModel(5, 0, Integer.MAX_VALUE, 1));
        private final JRadioButton plainButton = new JRadioButton();
        private final JRadioButton recursiveButton = new JRadioButton();
        private final JRadioButton depthButton = new JRadioButton();

        private ConfigPanel() {
            super("Pick");

            ButtonGroup group = new ButtonGroup();

            addField("Plain", plainButton);
            plainButton.addActionListener(e3 -> depthSpinner.setEnabled(false));
            group.add(plainButton);

            addField("Recursive", recursiveButton);
            recursiveButton.addActionListener(e2 -> depthSpinner.setEnabled(false));
            group.add(recursiveButton);

            addField("Depth", depthButton);
            depthButton.addActionListener(e1 -> depthSpinner.setEnabled(true));
            group.add(depthButton);

            gridPanel.set(2, 2, depthSpinner);

            defaultButton.addActionListener(e -> {
                FileChooser fileChooser = new FileChooser();
                if (fileChooser.showOpenDialog(null) == APPROVE_OPTION)
                    for (File file : fileChooser.getSelectedFiles())
                        handle("General", file, getDepth());

            });
        }

        public int getDepth() {
            if (plainButton.isSelected())
                return PLAIN;

            if (recursiveButton.isSelected())
                return RECURSIVE;

            return (int) depthSpinner.getValue();
        }
    }
}
